package megalopolis.common;

/**
 * User: Kirill
 * Date: 19.02.2008
 */
public abstract class ManagableThread implements Runnable {

	private boolean initialized;

    private boolean started;

	private boolean needStop;

	private long stepTime;

	protected ManagableThread(long stepTime) {
		this.stepTime = stepTime;
	}

	public void run() {
		while (!needStop()) {
			long startTime = System.currentTimeMillis();
			threadStep();
			long endTime = System.currentTimeMillis();
			if (endTime - startTime < stepTime) {
				try {
					Thread.sleep(stepTime - endTime + startTime);
				} catch (InterruptedException e) {
					// do nothing
				}
			}
		}
	}

	public abstract void threadStep();

    public synchronized final void start() {
		if (!initialized) {
			init();
			initialized = true;
		}
		if (!started) {
            new Thread(this).start();
            started = true;
        }
    }

	protected void init() {
	}

	public synchronized final void stop() {
		if (started) {
			needStop = true;
		}
	}

	private synchronized boolean needStop() {
		return needStop;
	}
}
